package com.wit.witmg.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.*;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import javax.imageio.ImageIO;
import javax.net.ssl.HttpsURLConnection;
import javax.servlet.http.HttpServletRequest;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Configuration
public class HttpUtils {
    public static HttpUtils instance;

    @PostConstruct
    public void init() {
        instance = this;
    }

    public String doPost(String url, Map<String, Object> map) {
        return httpFun(url, map, HttpMethod.POST);
    }

    public String doGet(String url, Map<String, Object> map) {
        return httpFun(url, map, HttpMethod.GET);
    }

    public String doGet(String url) {
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        HttpEntity<String> entity = new HttpEntity<>(headers);
        return restTemplate.exchange(url , HttpMethod.GET, entity, String.class).getBody();
    }

    public String doGetDY(String url,String accessToken,Map<String, Object> map) {
        return httpFunDY(url,accessToken,map,HttpMethod.GET);
    }
    public String doPostDY(String url,String accessToken,Map<String, Object> map) {
        return httpFunDY(url,accessToken,map,HttpMethod.POST);
    }

    private String httpFun(String url, Map<String, Object> map, HttpMethod method) {
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        HttpEntity<String> entity = new HttpEntity<>(headers);
        String param = "";
        if (map != null) {
            Iterator iter = map.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry entry = (Map.Entry) iter.next();
                Object key = entry.getKey();
                Object val = entry.getValue();
                param += (param.equals("") ? "?" : "&") + key + "=" + val;
            }
        }
        return restTemplate.exchange(url + param, method, entity, String.class).getBody();
    }

    private String httpFunDY(String url,String accessToken, Map<String, Object> map, HttpMethod method) {
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        headers.add("access-token", accessToken);
        HttpEntity<String> entity = new HttpEntity<>(headers);
        String param = "";
        if (map != null) {
            Iterator iter = map.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry entry = (Map.Entry) iter.next();
                Object key = entry.getKey();
                Object val = entry.getValue();
                param += (param.equals("") ? "?" : "&") + key + "=" + val;
            }
        }
        return restTemplate.exchange(url + param, method, entity, String.class).getBody();
    }

    /**
     * 向目的URL发送post请求
     *
     * @param url    目的url
     * @param params 发送的参数
     * @return ResultVO
     */
    public String sendPostRequest(String url, MultiValueMap<String, Object> params) {
        RestTemplate client = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        // 以表单的方式提交
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        //将请求头部和参数合成一个请求
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers);
        //执行HTTP请求，将返回的结构使用ResultVO类格式化
        return client.postForObject(url, requestEntity, String.class);
    }

    public String checkImg(MultipartFile multipartFile, String accessToken) throws Exception {
        //微信开放接口链接
        String url = "https://api.weixin.qq.com/wxa/img_sec_check?access_token=" + accessToken;
        // 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的
        HttpClient httpclient = HttpClients.createDefault();
        //创建一个post请求
        HttpPost request = new HttpPost(url);
        //设置响应头   （ application/octet-stream：二进制流，不知道下载文件类型）
        request.addHeader("Content-Type", "application/octet-stream");
        //输入流,获取输入图片的输入流
        InputStream inputStream = multipartFile.getInputStream();
        try {
            //创建一个byte数组，和输入的文件输入流大小一样
            byte[] byt = new byte[inputStream.available()];
            //从输入流中读取全部，并将其存储在缓冲区数组byt 中。
            inputStream.read(byt);
            //定制提交内容
            request.setEntity(new ByteArrayEntity(byt, ContentType.create("image/jpg")));
            //由客户端执行(发送) 请求, 执行校验
            HttpResponse response = httpclient.execute(request);
            // 从响应模型中获取响应实体
            org.apache.http.HttpEntity entity = response.getEntity();
            String result = EntityUtils.toString( entity, "UTF-8");// 转成string
            //打印校验结果
            System.out.println("result：" + result);
            return result;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return "";
    }

    //上传文件
    public String uploadFile(String url,MultipartFile multipartFile,String contentType) throws Exception {
        // 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的
        HttpClient httpclient = HttpClients.createDefault();
        //创建一个post请求
        HttpPost request = new HttpPost(url);
        //设置响应头   （ application/octet-stream：二进制流，不知道下载文件类型）
        request.addHeader("Content-Type", "application/octet-stream");
        //输入流,获取输入图片的输入流
        InputStream inputStream = multipartFile.getInputStream();
        try {
            //创建一个byte数组，和输入的文件输入流大小一样
            byte[] byt = new byte[inputStream.available()];
            //从输入流中读取全部，并将其存储在缓冲区数组byt 中。
            inputStream.read(byt);
            //定制提交内容
            request.setEntity(new ByteArrayEntity(byt, ContentType.create(contentType)));
            //由客户端执行(发送) 请求, 执行校验
            HttpResponse response = httpclient.execute(request);
            // 从响应模型中获取响应实体
            org.apache.http.HttpEntity entity = response.getEntity();
            String result = EntityUtils.toString( entity, "UTF-8");// 转成string
            //打印校验结果
            System.out.println("result：" + result);
            return result;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return "";
    }

    public String checkMsg(String accessToken,String content){
        //微信开放接口链接
        String url = "https://api.weixin.qq.com/wxa/msg_sec_check?access_token" + accessToken+"&content="+content;
        // 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的
        HttpClient httpclient = HttpClients.createDefault();
        //创建一个post请求
        HttpPost request = new HttpPost(url);
        //设置响应头   （ application/octet-stream：二进制流，不知道下载文件类型）
        request.addHeader("Content-Type", "application/json");
        try {
//            MultiValueMap map = new LinkedMultiValueMap();
//            map.put("content",content);
//            request.setEntity(new HttpEntity(map,));
            HttpResponse response = httpclient.execute(request);
            // 从响应模型中获取响应实体
            org.apache.http.HttpEntity entity = response.getEntity();
            String result = EntityUtils.toString( entity, "UTF-8");// 转成string
            //打印校验结果
            System.out.println("result：" + result);
            return result;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }

    public String postJson(String url){
        //微信开放接口链接
        // 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的
        HttpClient httpclient = HttpClients.createDefault();
        //创建一个post请求
        HttpPost request = new HttpPost(url);
        //设置响应头   （ application/octet-stream：二进制流，不知道下载文件类型）
        request.addHeader("Content-Type", "application/json");
        try {
//            MultiValueMap map = new LinkedMultiValueMap();
//            map.put("content",content);
//            request.setEntity(new HttpEntity(map,));
            HttpResponse response = httpclient.execute(request);
            // 从响应模型中获取响应实体
            org.apache.http.HttpEntity entity = response.getEntity();
            String result = EntityUtils.toString( entity, "UTF-8");// 转成string
            //打印校验结果
            System.out.println("result：" + result);
            return result;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }


    public String doPostParams(String url,Map<String, Object> map) {

        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        // 参数是普通参数
//        HttpPost httpPost = getStrHttpPost(POST_URL_PARAMS, id);
        // 参数是对象
        HttpPost httpPost = getObjectHttpPost(url,map);
        // 设置ContentType(注:如果只是传普通参数的话,ContentType不一定非要用application/json)
        httpPost.setHeader("Content-Type", "application/json;charset=utf8");
//        httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;application/json;charset=utf8");
//        httpPost.setHeader("Accept", "application/json");
//        httpPost.setHeader("Authorization", "bearer");
        CloseableHttpResponse response = null;
        try {
            response = httpClient.execute(httpPost);
            org.apache.http.HttpEntity httpEntity = response.getEntity();
            if (HttpStatus.SC_OK == response.getStatusLine().getStatusCode() && null != httpEntity) {
                return  EntityUtils.toString(httpEntity);
            }
        } catch (IOException e) {
            return null;
        }
        return null;
    }

    public String tongueGet(String url){
        String secretId="103961172";
        String secretKey="bd86b1b4229b4575b6e9a5740d021437";
        String timestamp=System.currentTimeMillis()+"";
        String sign=Md5Util.MD5Encode(secretId+ timestamp+ secretKey);
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/json;charset=utf8");
        headers.add("secretId",secretId);
        headers.add("timestamp",timestamp);
        headers.add("sign",sign);
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        HttpEntity<String> entity = new HttpEntity<>(headers);
        return restTemplate.exchange(url , HttpMethod.GET, entity, String.class).getBody();


    }

    public String tongue(Map<String, Object> map) {
        String url="https://xapi.xunai-tech.com/xunai-saas/saasApi/v1/tongue/tongueAnalysis";
        String secretId="103961172";
        String secretKey="bd86b1b4229b4575b6e9a5740d021437";
        String timestamp=System.currentTimeMillis()+"";
        String sign=Md5Util.MD5Encode(secretId+ timestamp+ secretKey);
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        // 参数是普通参数
//        HttpPost httpPost = getStrHttpPost(POST_URL_PARAMS, id);
        // 参数是对象
        HttpPost httpPost = getObjectHttpPost(url,map);
        // 设置ContentType(注:如果只是传普通参数的话,ContentType不一定非要用application/json)
        httpPost.setHeader("Content-Type", "application/json;charset=utf8");
        httpPost.setHeader("secretId",secretId);
        httpPost.setHeader("timestamp",timestamp);
        httpPost.setHeader("sign",sign);
//        httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;application/json;charset=utf8");
////        httpPost.setHeader("Accept", "application/json");
//        httpPost.setHeader("Authorization", "bearer");
        CloseableHttpResponse response = null;
        try {
            response = httpClient.execute(httpPost);
            org.apache.http.HttpEntity httpEntity = response.getEntity();
            if (HttpStatus.SC_OK == response.getStatusLine().getStatusCode() && null != httpEntity) {
                return  EntityUtils.toString(httpEntity);
            }
        } catch (IOException e) {
            return null;
        }
        return null;
    }

    public HttpPost getObjectHttpPost(String url,Map<String, Object> map) {

        HttpPost httpPost = new HttpPost(url);
        // 将JAVA对象转换为Json字符串
        String jsonString = JSON.toJSONString(map);
        StringEntity stringEntity = new StringEntity(jsonString, "utf8");
        // post请求是将参数放在请求体里面传过去的
        httpPost.setEntity(stringEntity);
        return httpPost;
    }


    /**
     * 上传临时素菜
     * 1、临时素材media_id是可复用的。
     * 2、媒体文件在微信后台保存时间为3天，即3天后media_id失效。
     * 3、上传临时素材的格式、大小限制与公众平台官网一致。
     * @return
     */
    public String uploadTemp(String urlString,File file){
        String result=null;
        String mediaId=null;
        try {
            URL url=new URL(urlString);
            HttpsURLConnection conn=(HttpsURLConnection) url.openConnection();
            conn.setRequestMethod("POST");//以POST方式提交表单
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setUseCaches(false);//POST方式不能使用缓存
            //设置请求头信息
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setRequestProperty("Charset", "UTF-8");
            //设置边界
            String BOUNDARY="----------"+System.currentTimeMillis();
            conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
            //请求正文信息
            //第一部分
            StringBuilder sb=new StringBuilder();
            sb.append("--");//必须多两条道
            sb.append(BOUNDARY);
            sb.append("\r\n");
            sb.append("Content-Disposition: form-data;name=\"media\"; filename=\"" + file.getName()+"\"\r\n");
            sb.append("Content-Type:application/octet-stream\r\n\r\n");
            System.out.println("sb:"+sb);

            //获得输出流
            OutputStream out=new DataOutputStream(conn.getOutputStream());
            //输出表头
            out.write(sb.toString().getBytes("UTF-8"));
            //文件正文部分
            //把文件以流的方式 推送道URL中
            DataInputStream din=new DataInputStream(new FileInputStream(file));
            int bytes=0;
            byte[] buffer=new byte[1024];
            while((bytes=din.read(buffer))!=-1){
                out.write(buffer,0,bytes);
            }
            din.close();
            //结尾部分
            byte[] foot=("\r\n--" + BOUNDARY + "--\r\n").getBytes("UTF-8");//定义数据最后分割线
            out.write(foot);
            out.flush();
            out.close();
            if(HttpsURLConnection.HTTP_OK==conn.getResponseCode()){

                StringBuffer strbuffer=null;
                BufferedReader reader=null;
                try {
                    strbuffer=new StringBuffer();
                    reader=new BufferedReader(new InputStreamReader(conn.getInputStream()));
                    String lineString=null;
                    while((lineString=reader.readLine())!=null){
                        strbuffer.append(lineString);

                    }
                    if(result==null){
                        result=strbuffer.toString();
                        return  result;
                        /**
                         * 这里的缩略图和image是不一样的，你们可以试一下
                         */
//                        JSONObject jsonObj = JSONObject.parseObject(result);
//                        System.out.println(jsonObj);
//                        String typeName = "media_id";
////                        if(!"image".equals(fileType)){
////                            typeName = fileType + "_media_id";
////                        }
//                        mediaId = jsonObj.getString(typeName);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }finally{
                    if(reader!=null){
                        reader.close();
                    }
                }

            }
        }  catch (IOException e) {
            e.printStackTrace();
        }
        return mediaId;
    }

    //微信第三方注册
    public String wxReg(String urlString,JSONObject map){
        String result=null;
        try {
            URL url = new URL(urlString);
            HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setUseCaches(false);//POST方式不能使用缓存
            conn.setRequestMethod("POST");//以POST方式提交表单
            //设置请求头信息
//            conn.setRequestProperty("Connection", "Keep-Alive");
//            conn.setRequestProperty("Charset", "GBK");
//            conn.setRequestProperty("Content-Type", "application/json;charset=utf8");
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            conn.setRequestProperty("Accept", "application/json");
            conn.setRequestProperty("Authorization", "bearer");
            conn.setInstanceFollowRedirects(false);
            //建立连接
            conn.connect();
//            String s="{\"name\":\"温州市鹿城区南汇镜像兀文化传媒工作室\",\"code\":\"92330302MA2CR01Y3B\",\"code_type\": 1,\"legal_persona_wechat\": \"jing222r\",\"legal_persona_name\":\"王静\",\"component_phone\":\"13957737708\"}";
//            result = getReturn(conn,"{\"name\":\"温州市鹿城区南汇镜像兀文化传媒工作室\",\"code\":\"92330302MA2CR01Y3B\",\"code_type\": 1,\"legal_persona_wechat\": \"jing222r\",\"legal_persona_name\":\"王静\",\"component_phone\":\"13957737708\"}");
            result = getReturn(conn,map.toJSONString());
        }catch (Exception e){}
        return result;
    }
    public static String getReturn(HttpsURLConnection connection,String jsr){
        try{
            StringBuffer buffer = new StringBuffer();
            byte[] bytes = jsr.getBytes();
            OutputStream outputStream = connection.getOutputStream();
            outputStream.write(bytes);
            outputStream.flush();
            outputStream.close();
            //将返回的输入流转换成字符串
            InputStream inputStream = connection.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            return buffer.toString();
        }catch (Exception e){
        }
        return null;
    }

    //获取小程序二维码
    public String getMiniProgramCode(String accessToken, String scene, String page) {
        String uri="https://api.weixin.qq.com/wxa/getwxacodeunlimit";
        HashMap<String, Object> body = new HashMap<>();
        body.put("scene", scene);
        body.put("page", page);
        body.put("width", 120);
        HttpEntity<HashMap<String, Object>> httpEntity = new HttpEntity<>(body, null);
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<byte[]> entity = restTemplate.exchange(uri + "?access_token=" + accessToken, HttpMethod.POST, httpEntity, byte[].class);
        byte[] buffer = entity.getBody();
        // 成功时微信服务直接返回小程序码的二进制数据，字节数组的长度会很大（大概是60000多）
        if (entity.getStatusCode().value() != HttpStatus.SC_OK || buffer == null || buffer.length < 200) {
            return "";
        }
//        //保存文件
//        String fileName=scene.replace("=","_")+".png";
//        String path=StringUtils.instance.getQrDir();
//        try {
//            FileUtil.uploadFile(buffer, path, fileName);
//        }catch (Exception e){}
        return Base64Util.encode(buffer);
    }

    //获取普通小程序二维码
    public String getQrEasy(String accessToken, String path) {
        String uri="https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token="+accessToken;
        HashMap<String, Object> body = new HashMap<>();
        body.put("path", path);
        body.put("width", 400);
        HttpEntity<HashMap<String, Object>> httpEntity = new HttpEntity<>(body, null);
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<byte[]> entity = restTemplate.exchange(uri, HttpMethod.POST, httpEntity, byte[].class);
        byte[] buffer = entity.getBody();
        // 成功时微信服务直接返回小程序码的二进制数据，字节数组的长度会很大（大概是60000多）
        if (entity.getStatusCode().value() != HttpStatus.SC_OK || buffer == null || buffer.length < 200) {
            return "";
        }
        //裁剪到图片下面文本部分
        try {
            buffer= FileUtil.cropImage(buffer,0,0,400,350);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return Base64Util.encode(buffer);
    }

    public String execWxReg(String url,Map<String, Object> map ){
        String jsonStr = JSONObject.toJSONString(map);
        String[] cmds = {"curl",""+url+"" ,
                "-H", "Content-Type:application/x-www-form-urlencoded;charset=gbk",
                "-H", "Authorization:bearer",
                "-H", "Accept: application/json",
                "-X","POST",
                "-d",""+jsonStr+""};   //超级注意：这个拼接json串的时候不要拼接双引号或者单引号，这个是踩坑提示，因为这个改了好久
        return execCurl(cmds);
    }

    /**
     * java 调用 Curl的方法
     * @param cmds
     * @return
     */
    public String execCurl(String[] cmds) {
        ProcessBuilder process = new ProcessBuilder(cmds);
        Process p;
        try {
            p = process.start();
            BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
            StringBuilder builder = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                builder.append(line);
                builder.append(System.getProperty("line.separator"));
            }
            return builder.toString();

        } catch (IOException e) {
            System.out.print("获取线程异常"+e);
        }
        return null;
    }

    /**
     * 将通知参数转化为字符串
     * @param request
     * @return
     */
    public String readData(HttpServletRequest request) {
        BufferedReader br = null;
        try {
            StringBuilder result = new StringBuilder();
            br = request.getReader();
            for (String line; (line = br.readLine()) != null; ) {
                if (result.length() > 0) {
                    result.append("\n");
                }
                result.append(line);
            }
            return result.toString();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }



    public BufferedImage loadImageFromUrl(String imageUrl) {
        try {
            URL url = new URL(imageUrl);
            return ImageIO.read(url);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}